package me.firstapp.repository.bbs.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.stereotype.Repository;

import me.firstapp.common.utils.DateUtils;
import me.firstapp.common.utils.Page;
import me.firstapp.common.utils.StrUtils;
import me.firstapp.module.bbs.Topic;
import me.firstapp.repository.base.impl.EntityRepositoryImpl;
import me.firstapp.repository.bbs.TopicRepository;

@Repository
public class TopicRepositoryImpl extends EntityRepositoryImpl<Topic> implements TopicRepository {

	@Override
	protected Class<Topic> getPersistentClass() {
		return Topic.class;
	}

	public Page<Topic> findTopicsPage(Integer pageNo, Integer pageSize, Long sectionId, Long memberId,
			Integer recommend, String sortParam, String sortType, Long apiClientId) {
		Map<String, Object> parameters = new HashMap<String, Object>();
		StringBuilder sql = new StringBuilder(" FROM Topic bean WHERE 1=1 ");

		sql.append(" AND bean.apiClientId =:apiClientId ");
		parameters.put("apiClientId", apiClientId);

		if (sectionId != null) {
			sql.append(" AND bean.section.id=:sectionId ");
			parameters.put("sectionId", sectionId);
		}

		if (memberId != null) {
			sql.append(" AND bean.member.id=:memberId ");
			parameters.put("memberId", memberId);
		}

		if (recommend != null) {
			sql.append(" AND bean.recommend=:recommend ");
			parameters.put("recommend", recommend);
		}

		if (StrUtils.isNotNULL(sortParam) && StrUtils.isNotNULL(sortType)) {
			sql.append(" ORDER BY bean." + sortParam + " " + sortType);
		} else {
			sql.append(" ORDER BY bean.recommend DESC, bean.createTime DESC");
		}

		return super.queryForPage(Topic.class, sql.toString(), parameters, pageNo, pageSize);
	}

	public Topic findTopicByTitle(String title, Long apiClientId) {
		Map<String, Object> parameters = new HashMap<String, Object>();
		StringBuilder sql = new StringBuilder(" FROM Topic bean WHERE 1=1 ");

		sql.append(" AND bean.apiClientId =:apiClientId ");
		parameters.put("apiClientId", apiClientId);

		sql.append(" AND bean.title=:title ");
		parameters.put("title", title);

		List<Topic> topics = super.query(Topic.class, sql.toString(), parameters);
		return topics.isEmpty() ? null : topics.get(0);
	}

	@Override
	public Long findTopicsCountsByMemberId(Long memberId, Long apiClientId) {
		Map<String, Object> parameters = new HashMap<String, Object>();
		StringBuilder sql = new StringBuilder("SELECT COUNT(bean.id) FROM Topic bean WHERE 1=1 ");

		sql.append(" AND bean.apiClientId =:apiClientId ");
		parameters.put("apiClientId", apiClientId);

		sql.append(" AND bean.member.id=:memberId ");
		parameters.put("memberId", memberId);

		List<Long> result = super.query(Long.class, sql.toString(), parameters);
		return result.isEmpty() ? 0 : result.get(0);
	}

	@Override
	public List<Topic> findSomeTopics(Long memberId, Long sectionId, Integer counts, Long apiClientId) {
		Map<String, Object> parameters = new HashMap<String, Object>();
		StringBuilder sql = new StringBuilder(" FROM Topic bean WHERE 1=1 ");

		sql.append(" AND bean.apiClientId =:apiClientId ");
		parameters.put("apiClientId", apiClientId);
		if (memberId != null) {
			sql.append(" AND bean.member.id=:memberId ");
			parameters.put("memberId", memberId);
		}
		if (sectionId != null) {
			sql.append(" AND bean.section.id=:sectionId ");
			parameters.put("sectionId", sectionId);
		}
		sql.append(" ORDER BY createTime DESC");
		return super.queryForLimit(Topic.class, sql.toString(), parameters, counts);
	}

	@Override
	public Page<Topic> findTopicsPageByParams(Integer pageNo, Integer pageSize, Map<String, Object> searchParams,
			String sortParam, String sortType, Date startTime, Date endTime, Long apiClientId) {
		Map<String, Object> parameters = new HashMap<String, Object>();
		StringBuilder sql = new StringBuilder(" FROM Topic bean WHERE 1=1 ");

		if (searchParams != null) {
			Set<String> keys = searchParams.keySet();
			for (String key : keys) {
				Object value = searchParams.get(key);
				if (value != null) {
					if ("sectionId".equals(key)) {
						String _value = (String) value;
						Long sectionId = Long.valueOf(_value);
						sql.append(" AND bean.section.id =:value ");
						parameters.put("value", sectionId);
					} else if ("recommend".equals(key)) {
						String _value = (String) value;
						Integer recommend = Integer.valueOf(_value);
						sql.append(" AND bean.recommend =:value ");
						parameters.put("value", recommend);
					} else if ("memberId".equals(key)) {
						sql.append(" AND bean.member.id =:value ");
						parameters.put("value", value);
					} else if ("sectionName".equals(key)) {
						sql.append(" AND bean.section.name LIKE :value ");
						parameters.put("value", "%" + value + "%");
					} else if ("memberName".equals(key)) {
						sql.append(" AND bean.member.name LIKE :value ");
						parameters.put("value", "%" + value + "%");
					} else {
						sql.append(" AND bean." + key + " LIKE :value ");
						parameters.put("value", "%" + value + "%");
					}
				}
			}
		}
		Date _startTime = null;
		if (startTime != null) {
			String startTimeStr = DateUtils.getDateStr(startTime, "yyyy-MM-dd") + " 00:00:00";
			_startTime = DateUtils.getDateFromDateStr(startTimeStr, "yyyy-MM-dd HH:mm:ss");

		}
		Date _endTime = null;
		if (endTime != null) {
			String endTimeStr = DateUtils.getDateStr(endTime, "yyyy-MM-dd") + " 23:59:59";
			_endTime = DateUtils.getDateFromDateStr(endTimeStr, "yyyy-MM-dd HH:mm:ss");
		}

		if (_startTime != null) {
			sql.append(" AND bean.createTime >=:startTime ");
			parameters.put("startTime", _startTime);
		}
		if (_endTime != null) {
			sql.append(" AND bean.createTime <=:endTime");
			parameters.put("endTime", _endTime);
		}

		sql.append(" AND bean.apiClientId =:apiClientId ");
		parameters.put("apiClientId", apiClientId);

		if (StrUtils.isNotNULL(sortParam) && StrUtils.isNotNULL(sortType)) {
			sql.append(" ORDER BY " + sortParam + " " + sortType);
		}

		return super.queryForPage(Topic.class, sql.toString(), parameters, pageNo, pageSize);
	}

	@Override
	public Long findTopicsCountsBySectionId(Long sectionId, Long apiClientId) {
		Map<String, Object> parameters = new HashMap<String, Object>();
		StringBuilder sql = new StringBuilder("SELECT COUNT(bean.id) FROM Topic bean WHERE 1=1 ");

		sql.append(" AND bean.apiClientId =:apiClientId ");
		parameters.put("apiClientId", apiClientId);

		sql.append(" AND bean.section.id=:sectionId ");
		parameters.put("sectionId", sectionId);

		List<Long> result = super.query(Long.class, sql.toString(), parameters);
		return result.isEmpty() ? 0 : result.get(0);
	}

	@Override
	public Topic findTopicById(Long id, Long apiClientId) {
		Map<String, Object> parameters = new HashMap<String, Object>();
		StringBuilder sql = new StringBuilder(" FROM Topic bean WHERE 1=1 ");

		sql.append(" AND bean.apiClientId =:apiClientId ");
		parameters.put("apiClientId", apiClientId);

		sql.append(" AND bean.id=:id ");
		parameters.put("id", id);

		List<Topic> topics = super.query(Topic.class, sql.toString(), parameters);
		return topics.isEmpty() ? null : topics.get(0);
	}

	@Override
	public Long findTopicsCountsByCreateTime(Date startTime, Date endTime, Long apiClientId) {
		StringBuilder sql = new StringBuilder("SELECT COUNT(bean.id) FROM Topic bean WHERE 1=1 ");
		Map<String, Object> parameters = new HashMap<>();

		Date _startTime = null;
		if (startTime != null) {
			String startTimeStr = DateUtils.getDateStr(startTime, "yyyy-MM-dd") + " 00:00:00";
			_startTime = DateUtils.getDateFromDateStr(startTimeStr, "yyyy-MM-dd HH:mm:ss");

		}
		Date _endTime = null;
		if (endTime != null) {
			String endTimeStr = DateUtils.getDateStr(endTime, "yyyy-MM-dd") + " 23:59:59";
			_endTime = DateUtils.getDateFromDateStr(endTimeStr, "yyyy-MM-dd HH:mm:ss");
		}

		if (startTime != null && endTime != null) {
			sql.append(" AND bean.createTime >=:startTime ");
			parameters.put("startTime", _startTime);
			sql.append(" AND bean.createTime <=:endTime ");
			parameters.put("endTime", _endTime);

		} else if (startTime != null && endTime == null) {
			sql.append(" AND bean.createTime >=:startTime ");
			parameters.put("startTime", _startTime);
		} else if (startTime == null && endTime != null) {
			sql.append(" AND bean.createTime <=:endTime ");
			parameters.put("endTime", _endTime);
		}

		List<Long> result = super.query(Long.class, sql.toString(), parameters);
		return result.isEmpty() ? 0 : result.get(0);
	}

}
